#!/bin/sh
# Build Debian root filesystem

OS="$1" # For example "debian"
ARCH="$2" # For example "armhf"
DIST="$3" # For example "buster"

set -ex

case "${OS}-${ARCH}" in
debian-armhf)
	KERNEL=linux-image-armmp
	URL=http://deb.debian.org/debian
	KERNEL_URL=http://packages.debian.org/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/sid
	;;
debian-arm64)
	KERNEL=linux-image-arm64
	URL=http://deb.debian.org/debian
	KERNEL_URL=http://packages.debian.org/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/sid
	;;
debian-i386)
	KERNEL=linux-image-686
	URL=http://deb.debian.org/debian
	KERNEL_URL=http://packages.debian.org/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/sid
	;;
debian-amd64)
	KERNEL=linux-image-amd64
	URL=http://deb.debian.org/debian
	KERNEL_URL=http://packages.debian.org/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/sid
	;;
ubuntu-amd64)
	KERNEL=linux-image-generic
	URL=http://archive.ubuntu.com/ubuntu
	KERNEL_URL=http://packages.ubuntu.com/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/gutsy
	;;
ubuntu-armhf|ubuntu-arm64)
	KERNEL=linux-image-generic
	URL=http://ports.ubuntu.com/ubuntu-ports
	KERNEL_URL=http://packages.ubuntu.com/"${DIST}"/"${KERNEL}"
	SCRIPT=/usr/share/debootstrap/scripts/gutsy
	;;
*)
	echo "Can't decide kernel package for \"${ARCH}\""
	exit 1
	;;
esac

case "${OS}-${ARCH}-${DIST}" in
debian-*-rc-buggy|debian-*-experimental)
	TARGET=sid
	KERNELSUITE="-t experimental"
	;;
*)
	TARGET="${DIST}"
	KERNELSUITE=""
	;;
esac

# Create fresh empty directory
TMP=$(mktemp -d -p "${PWD}" tmp-XXXXXX)
trap 'rm -rf "${TMP}"' EXIT INT TERM
cd "${TMP}"

# Build a Debian root filesystem (first stage)
debootstrap \
  --arch="${ARCH}" \
  --verbose \
  --variant=minbase \
  --foreign \
  --include=\
netbase,\
net-tools,\
systemd-sysv,\
u-boot-tools,\
initramfs-tools,\
openssh-server,\
nano \
  "${TARGET}" \
  debian \
  "${URL}" \
  "${SCRIPT}"

# Randomly generated root password
PASSWORD="${PASSWORD_OVERRIDE:-$(pwgen -B -A 6 1)}"

# Write apt sources config
case "${OS}-${ARCH}-${DIST}" in
debian-*-rc-buggy|debian-*-experimental)
	tee debian/tmp/sources.list <<- EOF
deb http://deb.debian.org/debian ${TARGET} main
deb-src http://deb.debian.org/debian ${TARGET} main
deb http://deb.debian.org/debian ${DIST} main
deb-src http://deb.debian.org/debian ${DIST} main
EOF
	;;
debian-*-sid|debian-*-unstable)
	tee debian/tmp/sources.list <<- EOF
deb http://deb.debian.org/debian ${DIST} main
deb-src http://deb.debian.org/debian ${DIST} main
EOF
	;;
debian-*)
	tee debian/tmp/sources.list <<- EOF
deb http://deb.debian.org/debian ${DIST} main
deb-src http://deb.debian.org/debian ${DIST} main
deb http://deb.debian.org/debian ${DIST}-updates main
deb-src http://deb.debian.org/debian ${DIST}-updates main
deb http://security.debian.org/debian-security ${DIST}-security main
deb-src http://security.debian.org/debian-security ${DIST}-security main
EOF
	;;
ubuntu-amd64-*)
	tee debian/tmp/sources.list <<- EOF
deb http://archive.ubuntu.com/ubuntu ${DIST} main universe
deb-src http://archive.ubuntu.com/ubuntu ${DIST} main universe
deb http://archive.ubuntu.com/ubuntu ${DIST}-updates main universe
deb-src http://archive.ubuntu.com/ubuntu ${DIST}-updates main universe
deb http://archive.ubuntu.com/ubuntu ${DIST}-security main universe
deb-src http://archive.ubuntu.com/ubuntu ${DIST}-security main universe
EOF
	;;
ubuntu-*)
	tee debian/tmp/sources.list <<- EOF
deb http://ports.ubuntu.com/ubuntu-ports ${DIST} main universe
deb-src http://ports.ubuntu.com/ubuntu-ports ${DIST} main universe
deb http://ports.ubuntu.com/ubuntu-ports ${DIST}-updates main universe
deb-src http://ports.ubuntu.com/ubuntu-ports ${DIST}-updates main universe
deb http://ports.ubuntu.com/ubuntu-ports ${DIST}-security main universe
deb-src http://ports.ubuntu.com/ubuntu-ports ${DIST}-security main universe
EOF
	;;
esac

case "${OS}-${ARCH}-${DIST}" in
debian-*-rc-buggy|debian-*-experimental)
	# For Debian Experimental, set lower priority to "experimental"
	tee debian/tmp/priority-experimental <<- EOF
Package: *
Pin: release o=Debian,a=experimental
Pin-Priority: 300
EOF
	;;
*)
	;;
esac

cp -rv --preserve=mode ../2nd-stage-files/pre-2nd-stage-files/* debian
cp -rv --preserve=mode ../2nd-stage-files/pre-2nd-stage-files-${ARCH}/* debian

# Copy ARM emulation stuff
cp -v /usr/bin/qemu-*-static debian/usr/bin || :

# Build a Debian root filesystem (second stage)
chroot debian /bin/sh -ex <<- EOF
/debootstrap/debootstrap --second-stage
/bin/mv /tmp/sources.list /etc/apt/sources.list
/bin/mv /tmp/priority-experimental /etc/apt/preferences.d/priority-experimental || :
/usr/bin/apt-get update
/usr/bin/apt-get -y upgrade
/usr/bin/apt-get -y --no-install-recommends ${KERNELSUITE} install "${KERNEL}"
/usr/bin/apt-get -y install systemd-timesyncd || :
/usr/bin/apt-get -y install systemd-resolved || :
/usr/bin/apt-get clean
/bin/rm -rf /var/lib/apt/lists/*
echo "kernel-url,${KERNEL_URL}\n" >> /tmp/versions.csv
/usr/bin/dpkg-query --showformat='kernel,\${Version}\n' --show "${KERNEL}" >> /tmp/versions.csv
/usr/bin/systemctl enable systemd-networkd.service
/usr/bin/systemctl enable systemd-resolved.service
/usr/bin/systemctl enable systemd-timesyncd.service
/usr/bin/systemctl enable generate-ssh-host-keys.service
/bin/rm -f /var/log/*.log
/bin/echo "root:${PASSWORD}" | /usr/sbin/chpasswd
/bin/sed -i "s/#*\s*PermitRootLogin .*/PermitRootLogin yes/" /etc/ssh/sshd_config
EOF

# Remove ARM emulation stuff again
rm -v debian/usr/bin/qemu-*-static || :

# Remove ssh host keys, they will be generated on first boot by generate-ssh-host-keys.service
rm -v debian/etc/ssh/ssh_host_*_key* || :

cp -rv --preserve=mode ../2nd-stage-files/post-2nd-stage-files/* debian

# Set hostname
echo "${OS}" > debian/etc/hostname

# Set resolv.conf
ln -sf /run/systemd/resolve/stub-resolv.conf debian/etc/resolv.conf

# List all files
find debian ! -type d -printf "/%P\n" | sort > files.txt

mv debian/tmp/versions.csv versions.csv

# Make a ext4 filesystem of this and put it into the image
# >>> ((3800000000 - 32 * 1024 * 1024) // (1024 * 1024)) * (1024 * 1024)
# 3765436416
rm -f ext4.img
fallocate -l 3765436416 ext4.img
mkfs.ext4 -d debian ext4.img
pigz ext4.img

mkdir -p "${ARTIFACTS_DIR:-/artifacts}"
cp -v files.txt "${ARTIFACTS_DIR:-/artifacts}/${OS}-${DIST}-${ARCH}-${PASSWORD}.bin.gz.files.txt"
cp -v versions.csv "${ARTIFACTS_DIR:-/artifacts}/${OS}-${DIST}-${ARCH}-${PASSWORD}.bin.gz.versions.csv"
cp -v ext4.img.gz "${ARTIFACTS_DIR:-/artifacts}/${OS}-${DIST}-${ARCH}-${PASSWORD}.bin.gz"
